package com.dkd.flow.utils;

import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dkd.common.core.domain.entity.SysUser;
import com.dkd.common.enums.UpdateType;
import com.dkd.common.utils.EbUtils;
import com.dkd.flow.domain.EProcessInstances;
import com.dkd.flow.domain.EProcessTask;
import com.dkd.flow.emums.TaskActionType;
import com.dkd.flow.emums.TaskStatus;
import com.dkd.flow.emums.TaskType;
import com.dkd.flow.mapper.EProcessDefinitionMapper;
import com.dkd.flow.mapper.EProcessInstancesMapper;
import com.dkd.flow.mapper.EProcessTaskMapper;
import com.dkd.flow.rules.BaseRules;
import com.dkd.flow.rules.conditions.ConditionsRule;
import com.dkd.system.service.impl.SysUserServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;
import java.util.function.Function;

@Service
public class TaskCreate {
    @Autowired
    protected EProcessInstancesMapper eProcessInstancesMapper;
    @Autowired
    protected EProcessTaskMapper eProcessTaskMapper;
    @Autowired
    protected ConditionsRule conditionsRule;
    @Autowired
    protected BaseRules baseRules;
    @Autowired
    protected NodeUtils nodeUtils;
    @Autowired
    protected SysUserServiceImpl sysUserServiceImpl;
    @Autowired
    protected EProcessDefinitionMapper eProcessDefinitionMapper;

    // 创建审批人任务，这个流程任务，只是标识一个状态，没有具体的操作。
    public EProcessTask approverTask(EProcessInstances eProcessInstances,
            SysUser approver,
            String curProcessDesignId,
            TaskStatus taskStatus,
            Long selfId,
            Long actionTaskId,
            Long preTaskId,
            // 上一个节点的id，一定是OPERATION_TASK的taskId
            Long taskGroupId,
            String formValue,
            TaskActionType taskActionType) {
        EProcessTask eProcessTask = new EProcessTask();
        eProcessTask.setID(selfId);
        eProcessTask.setPreTaskId(preTaskId);
        eProcessTask.setActionTaskId(actionTaskId);
        eProcessTask.setFormValue(formValue);
        eProcessTask.setTaskGroupId(taskGroupId);
        eProcessTask.setProcessDefinitionId(eProcessInstances.getProcessDefinitionId());
        eProcessTask.setProcessInstancesId(eProcessInstances.getID());
        eProcessTask.setApprover(approver.getUserId());
        // 任务类型
        eProcessTask.setTaskType(TaskType.APPROVER_TASK.getValue().longValue());
        // 任务状态
        eProcessTask.setTaskStatus(taskStatus.getValue().longValue());
        eProcessTask.setTaskActionType(taskActionType.getValue().longValue());
        eProcessTask.setActionTaskId(actionTaskId);
        // 设置任务对应流程定义的节点id
        eProcessTask.setProcessDesignId(curProcessDesignId);
        // 设置创建人
        EbUtils.setCreateByIfNull(eProcessTask,
                EProcessTask::getCreateBy,
                EProcessTask::setCreateBy);
        // 设置创建日期
        EbUtils.updateTableFields(UpdateType.ADD_FIELD,
                eProcessTask);
        Integer eProcessTaskResult = eProcessTaskMapper.insert(eProcessTask);
        if (eProcessTaskResult <= 0) {
            throw new RuntimeException("创建审批人任务失败，审批人ID: " + approver);
        }
        return eProcessTask;
    }

    // 创建审批人任务
    public void createApproverTask(EProcessInstances eProcessInstances,
            JSONObject node,
            Function<SysUser, EProcessTask> callback) {
        List<JSONObject> approverList = node.getJSONObject("properties").getList("approvers",
                JSONObject.class);
        if (approverList == null || approverList.size() < 1) {
            throw new RuntimeException("找不到审批人");
        }
        for (JSONObject approverJson : approverList) {
            String approverId = approverJson.getString("userId");
            SysUser approver = sysUserServiceImpl.getById(approverId);
            if (Objects.isNull(approver)) {
                throw new RuntimeException("找不到审批人，ID: " + approverId);
            }
            EProcessTask eProcessTask = callback.apply(approver);
        }
    }

    // 创建抄送人任务
    public void createCcTask(EProcessInstances eProcessInstances,
            JSONObject node,
            Long selfId,
            Long actionTaskId,
            Long preTaskId,
            // 上一个节点的id，一定是OPERATION_TASK的taskId
            Long taskGroupId,
            String formValue,
            TaskActionType taskActionType) {
        List<JSONObject> approverList = node.getJSONObject("properties").getList("approvers",
                JSONObject.class);
        if (approverList == null || approverList.size() < 1) {
            throw new RuntimeException("找不到审批人");
        }
        for (JSONObject approverJson : approverList) {
            String approverId = approverJson.getString("userId");
            SysUser approver = sysUserServiceImpl.getById(approverId);
            if (Objects.isNull(approver)) {
                throw new RuntimeException("找不到抄送人，ID: " + approverId);
            }
            EProcessTask eProcessTask = new EProcessTask();
            eProcessTask.setID(selfId);
            eProcessTask.setActionTaskId(actionTaskId);
            eProcessTask.setFormValue(formValue);
            eProcessTask.setTaskGroupId(taskGroupId);
            eProcessTask.setProcessDefinitionId(eProcessInstances.getProcessDefinitionId());
            eProcessTask.setProcessInstancesId(eProcessInstances.getID());
            eProcessTask.setApprover(approver.getUserId());
            eProcessTask.setTaskType(TaskType.CC_TASK.getValue().longValue());
            eProcessTask.setTaskActionType(TaskActionType.LOG_TASK.getValue().longValue());
            eProcessTask.setTaskStatus(TaskStatus.UNDER_APPROVAL.getValue().longValue());
            eProcessTask.setPreTaskId(preTaskId);
            eProcessTask.setActionTaskId(actionTaskId);
            // 设置任务对应流程定义的节点id
            eProcessTask.setProcessDesignId(node.getString("nodeId"));
            // 设置创建人
            EbUtils.setCreateByIfNull(eProcessTask,
                    EProcessTask::getCreateBy,
                    EProcessTask::setCreateBy);
            // 设置创建日期
            EbUtils.updateTableFields(UpdateType.ADD_FIELD,
                    eProcessTask);
            Integer eProcessTaskResult = eProcessTaskMapper.insert(eProcessTask);
            if (eProcessTaskResult <= 0) {
                throw new RuntimeException("创建抄送人任务失败，抄送人ID: " + approverId);
            }
        }
    }

    // 发起人创建流程任务
    public EProcessTask createLaunchTask(EProcessInstances eProcessInstances,
            JSONObject curNode,
            Integer isRestart,
            TaskStatus taskStatus,
            Long selfId,
            Long preTaskId,
            // 上一个节点的id，一定是OPERATION_TASK的taskId
            Long actionTaskId,
            SysUser liableUser,
            Long taskGroupId,
            String formValue,
            TaskActionType taskActionType) {
        if (Objects.isNull(liableUser)) {
            throw new RuntimeException("找不到发起人");
        }
        EProcessTask eProcessTask = new EProcessTask();
        eProcessTask.setID(selfId);
        eProcessTask.setActionTaskId(actionTaskId);
        eProcessTask.setFormValue(formValue);
        eProcessTask.setTaskGroupId(taskGroupId);
        // 是否驳回后，重新开始
        if (isRestart != null) {
            eProcessTask.setRestart(1);
        }
        eProcessTask.setProcessDefinitionId(eProcessInstances.getProcessDefinitionId());
        eProcessTask.setProcessInstancesId(eProcessInstances.getID());
        eProcessTask.setApprover(liableUser.getUserId());
        eProcessTask.setPreTaskId(preTaskId);
        // 任务类型
        eProcessTask.setTaskType(TaskType.INITIATOR_TASK.getValue().longValue());
        // 任务状态
        eProcessTask.setTaskStatus(taskStatus.getValue().longValue());
        // 任务操作类型
        eProcessTask.setTaskActionType(taskActionType.getValue().longValue());
        // 设置任务对应流程定义的节点id
        eProcessTask.setProcessDesignId(curNode.getString("nodeId"));
        // 设置创建人
        EbUtils.setCreateByIfNull(eProcessTask,
                EProcessTask::getCreateBy,
                EProcessTask::setCreateBy);
        // 设置创建日期
        EbUtils.updateTableFields(UpdateType.ADD_FIELD,
                eProcessTask);
        Integer eProcessTaskResult = eProcessTaskMapper.insert(eProcessTask);
        if (eProcessTaskResult <= 0) {
            throw new RuntimeException("创建发起人任务失败");
        }
        return eProcessTask;
    }

    // 生成操作组id
    public Long createAndSetOperationGroupId(EProcessInstances eProcessInstances) {
        Long operationGroupId = IdUtil.getSnowflakeNextId();
        eProcessInstances.setOperationGroupId(operationGroupId);
        return operationGroupId;
    }

    // 判断任务中是否有发起
    public Boolean checkTaskHasLaunch(Long taskGroupId) {
        Boolean has = false;
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("task_group_id",
                taskGroupId);
        queryWrapper.eq("task_status",
                TaskStatus.INITIATE_APPLICATION.getValue());
        has = eProcessTaskMapper.selectCount(queryWrapper) > 0;
        return has;
    }

    // 用审批人已审批数量，判断是否已经有操作组id，没有就要生成
    public Long getTaskGroupId(EProcessInstances eProcessInstances) {
        Long taskGroupId = eProcessInstances.getOperationGroupId();
        // 还没审批，需要生成操作组id
        Integer nodeApprovedCount = eProcessInstances.getNodeApprovedCount();
        if (nodeApprovedCount == null || nodeApprovedCount < 1) {
            taskGroupId = createAndSetOperationGroupId(eProcessInstances);
        }
        return taskGroupId;
    }

    // 清空实例中操作组id的存储
    public void clearOperationGroupId(EProcessInstances eProcessInstances) {
        eProcessInstances.setOperationGroupId(null);
        eProcessInstancesMapper.updateById(eProcessInstances);
    }

    /**
     * 查找同组下的指定任务类型的任务（OPERATION_TASK + RETURNED），排除当前操作任务
     */
    public List<EProcessTask> getOperationTasks(
            Long taskGroupId,
            Long excludeTaskId,
            TaskStatus taskStatus) {
        QueryWrapper<EProcessTask> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("TASK_GROUP_ID", taskGroupId);
        queryWrapper.eq("TASK_ACTION_TYPE", TaskActionType.OPERATION_TASK.getValue());
        queryWrapper.eq("TASK_STATUS", taskStatus.getValue());
        if (excludeTaskId != null) {
            queryWrapper.ne("ID", excludeTaskId);
        }
        return eProcessTaskMapper.selectList(queryWrapper);
    }
}
